<!--
TODO: Assertion
multi signal / multi histo
signal drag
 signal zoom
histo columns?
signal view align + sync

histogram delete element -> hide window
signal view - refresh scroll left
nexus: bit range assert
hide histo
div 10 attr

text select disable, code demo
zero based indices, missing attr/default attr in demo
-->
<!--
<script src="https://cdn.jsdelivr.net/npm/rete@1.5.2/build/rete.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-vue-render-plugin@0.5.1/build/vue-render-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-connection-plugin@0.9.0/build/connection-plugin.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/rete-lifecycle-plugin@1.0.0-beta.1/build/lifecycle-plugin.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/alight@0.14.1/alight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-area-plugin@0.2.1/build/area-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-context-menu-plugin@0.6.0/build/context-menu-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-comment-plugin@0.3.0/build/comment-plugin.min.js"></script>           	
<script src="https://cdn.jsdelivr.net/npm/rete-history-plugin@0.1.0/build/history-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rete-connection-mastery-plugin@0.1.0/build/connection-mastery-plugin.min.js"></script>

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/histogram-bellcurve.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
-->

<script src="offline/rete.min.js"></script>
<script src="offline/vue.min.js"></script>
<script src="offline/vue-render-plugin.min.js"></script>
<script src="offline/connection-plugin.min.js"></script>
<script src="offline/lifecycle-plugin.min.js"></script>
<script src="offline/alight.min.js"></script>
<script src="offline/lodash.min.js"></script>
<script src="offline/area-plugin.min.js"></script>
<script src="offline/context-menu-plugin.min.js"></script>
<script src="offline/comment-plugin.min.js"></script>           	
<script src="offline/history-plugin.min.js"></script>
<script src="offline/connection-mastery-plugin.min.js"></script>
<script src="offline/highcharts.js"></script>
<script src="offline/histogram-bellcurve.js"></script>
<link rel="stylesheet" href="offline/font-awesome.min.css">

<script src="signal.js"></script>
<script src="signalcanvas.js"></script>
<script src="signalhistogram.js"></script>
<script src="vuecontrols.js"></script>
<script src="retecontrols.js"></script>
<script src="retecomponents.js"></script>
<script src="demo.js"></script>
<script src="code.js"></script>
<script src="rtl433.js"></script>

<style>
html, body {
  height: 100%;
  width: 100%;
  margin: 0;
  overflow: hidden;
}

@media (prefers-color-scheme: dark) {
body {
  background: black;
}
}

.node .control input, .node .input-control input {
  width: 140px;
}
select, input {
  width: 100%;
  border-radius: 30px;
  background-color: white;
  padding: 2px 6px;
  border: 1px solid #999;
  font-size: 110%;
  width: 170px;
}

.note {
  position: absolute;
  top: 0;
  left: 0;
  background: #7ca2ba;
  color: white;
  width: 100%;
  text-align: center;
  padding: 0.5em;
  font-family: sans-serif;
  z-index: 1;
  a {
    color: #eee;
  }
}

#chart {
  width: 800px;
  height: 400px;
  position: absolute;
  left: 800px;
  top: 200px;
  border:3px #04b solid;
  border-radius:10px;
  display: none;
}

input:disabled { background: #ddd; color: #888}

#panel {width:150px; height:100%; overflow:auto; background:#b0b0b040; position:fixed; left:0px; top:0px;
  color:#ffffff; padding:10px;}
#panel button {margin-top:5px; margin-left:5px;}
</style>


<div id="rete"></div>
<div id="chart"></div>
<div id="panel"></div>

<script>
var parentWindow = null;
var numSocket = new Rete.Socket('Number value');
var arrSocket = new Rete.Socket('Array value');
var attrSocket = new Rete.Socket('Attributes');

var html = "Samples:<br>";
for (var i in demo)
  html += `<button onClick="openDemo('${i}')">${i}</button>`;
html += "<br><br>"
document.querySelector("#panel").innerHTML = html;
function openDemo(i)
{
  var d = demo[i];
  if (i.split("_")[0] == "do")
    d();
  else if (i.split("_")[0] == "decode" || i.split("_")[0] == "encode")
    return onNewModel(d);
  else if (i.split("_")[0] == "signal")
    return onNewData(d);
  else
    return onNewData(i.split(",").map(n=>parseInt(n)));
}

var onNewData;

(async () => {
    var container = document.querySelector('#rete');
    var components = [new InputSignal(), new SubArray(), new Quantize(),
      new Histogram(), new Filter(), new Split(), new Pairs(), new LookupTable(), new Print(), new ToInteger(), new If(),
      new Attributes(), new DisplaySignal(), new Assert(), new Count(),
      new Denoise(), new Select(), new Code(), new RevAttributes(), new Sequence(),
      new Rtl433()];

    var getComponent = name => components.find(c=>c.constructor.name == name)
    await getComponent("Rtl433").ready

    var editor = new Rete.NodeEditor('demo@0.1.0', container);
    editor.use(ConnectionPlugin.default);
    editor.use(VueRenderPlugin.default);    
    editor.use(ContextMenuPlugin.default);
    editor.use(AreaPlugin);
    editor.use(CommentPlugin.default);
    editor.use(HistoryPlugin);
    editor.use(ConnectionMasteryPlugin.default);
    editor.use(LifecyclePlugin.default);

    var engine = new Rete.Engine('demo@0.1.0');
    
    components.map(c => {
      editor.register(c);
      engine.register(c);
    });

    editor.on('process nodecreated noderemoved connectioncreated connectionremoved', async () => {
      console.log('process');
        await engine.abort();
        await engine.process(editor.toJSON());
        //console.log(generateCode(editor.toJSON()));
    });

    editor.on('zoom', (e) => {
        if (e.source === 'dblclick' && editor.selected?.list[0]?.name == "Input signal")
        {
          var node = editor.selected?.list[0];
          var _node = editor.nodes.find(n => n.id == node.id)
          var newsignal = prompt("Enter new signal", JSON.stringify(node.data.out.data));
          if (newsignal)
          {
            node.data.out = new Signal(JSON.parse(newsignal))
            editor.trigger('process');
          }
          return false;
        }
        return e.source !== 'dblclick';
    });

    onNewData = (data) => {
      for (var i in editor.nodes)
      {
        if (editor.nodes[i].name == "Input signal")
        {
          editor.nodes[i].data.out = new Signal(data)
          editor.trigger('process');
        }
      }
      return Promise.resolve();
    }

    onNewModel = async (model) => {
      var index = 0;
      var current = {};
      editor.clear();
      for (var i in model.components)
      {
        if (!("id" in model.components[i]))
        {
          index++;
          continue;
        }
        var component = await getComponent(model.components[i].id).createNode() 
        for (var j in model.components[i])
          if (j != "id")
          {
            if (j == "datatype")
              component.data[j].value = model.components[i][j]
            else
              component.data[j] = model.components[i][j]
          }
        component.position = [260 + (index%4)*250, 200 + Math.floor(index/4)*300]
        editor.addNode(component);
        current[i] = component;
        index++;
        if (model.components[i].id == "Code")
          index++; 
      }
      for (var c of model.connections)
      {
        var connOut = c[0].split(".");
        var connIn = c[1].split(".");

        var out = current[connOut[0]].outputs.get(connOut[1]);
        var inp = current[connIn[0]].inputs.get(connIn[1]);
        editor.connect(out, inp);      
      }
    }
    reteJson = () => editor.toJSON();
    if (document.location.hash.length > 2)
    {
//      var promise = Promise.resolve();
      var ids = document.location.hash.substr(1).split(";");//.map(id => ((id) => {console.log(id); return openDemo(id)}))
      var processId = () =>
      {
        if (ids.length == 0)
          return Promise.resolve();
        return openDemo(ids.shift()).then(processId)
      }
      processId().then(()=>{console.log("done"); editor.trigger('process')})
    }
    else
      onNewModel(demo.decode_came001unip);
    editor.view.resize();
    //AreaPlugin.zoomAt(editor);
    editor.view.area.zoom(0.75, 0, -120);
    editor.trigger('process');
/*
    if (parentWindow)
    {
      console.log("Editor Loaded signal");
      var event = new CustomEvent("EditorLoaded", {detail:{
        data: [],
        sender: window.document
      }});
      parentWindow.DispatchEvent(event);
    } else
      console.log("No parent ", parentWindow);
*/
})();

window.document.addEventListener('SignalChanged', (e) => { 
  console.log("Got data", e.detail.data);
  onNewData(e.detail.data);
}, false);

window.document.addEventListener('SetParent', (e) => { 
  console.log(e);
  parentWindow = e.detail.sender; 
  console.log("Set parent", parentWindow);
}, false);
</script>